#!/usr/bin/env python

import __main__
# This is going to require sqlalchemy 0.8 sooner than later.
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"]
import pkg_resources
pkg_resources.require(__requires__)

import tempfile
import time
import os
import subprocess
import shutil

from gssapi import Credentials
from gssapi.exceptions import GSSError
from requests_gssapi import HTTPSPNEGOAuth
from tahrir_api.dbapi import TahrirDatabase
import fedbadges.utils
import transaction
import requests

import fedora.client
import socket

import logging
log = logging.getLogger()
logging.basicConfig()

import fedmsg
import fedmsg.config

fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)


badge = None
http_client = None


def get_http_client():
    os.environ["KRB5_CLIENT_KTNAME"] = fm_config.get("keytab")
    try:
        creds = Credentials(usage="initiate")
    except GSSError as e:
        log.error("GSSError trying to authenticate with Kerberos", e)
    gssapi_auth = HTTPSPNEGOAuth(opportunistic_auth=True, creds=creds)
    session = requests.Session()
    session.auth = gssapi_auth
    return session


def clone_repo(repo):
    pwd = os.getcwd()
    command = 'git clone https://github.com/fedora-infra/%s.git %s'
    try:
        location = tempfile.mkdtemp()
        os.chdir(location)
        os.system(command % (repo, location))
    finally:
        os.chdir(pwd)
    return location


def gather_authors(location):
    pwd = os.getcwd()
    command = 'git log --raw | grep "^Author: " | sort | uniq -c'
    try:
        os.chdir(location)
        proc = subprocess.Popen([command], shell=True, stdout=subprocess.PIPE)
        out, err = proc.communicate()
        lines = out.split('\n')
        authors = [line.split('<')[-1].split('>')[0] for line in lines]
    finally:
        os.chdir(pwd)
    return authors


def emails_to_fas_accounts(emails):
    usernames = []
    for email in emails:
        result = http_client.get(
            "{}search/users/".format(fm_config['fasjson_base_url']),
            params={"email": email}
        )
        if not result.ok:
            continue
        response = result.json()
        if response["page"]["total_results"] != 1:
            continue
        usernames.append(response["result"][0]["username"])
    return usernames


def main():
    repos = ['tahrir', 'tahrir-api', 'fedbadges']
    for repo in repos:
        print "Trying %r" % repo
        location = clone_repo(repo)
        try:
            emails = gather_authors(location)
            print "Considering emails %r" % emails
            usernames = emails_to_fas_accounts(emails)
            print "Considering users  %r" % usernames
            award_badges(usernames)
        finally:
            shutil.rmtree(location)


def award_badges(usernames):
    for username in usernames:
        email = username + "@fedoraproject.org"
        if tahrir.assertion_exists(badge.id, email):
            print email, "already has", badge.id, "skipping."
            continue

        time.sleep(1)
        print "awarding", badge.id, "to", email
        try:
            transaction.begin()
            tahrir.add_assertion(badge.id, email, None)
            transaction.commit()
        except Exception as e:
            transaction.abort()
            print "Failure:", e


if __name__ == '__main__':
    uri = fm_config['badges_global']['database_uri']
    tahrir = TahrirDatabase(
        uri,
        notification_callback=fedbadges.utils.notification_callback,
    )
    badge = tahrir.get_badge(badge_id='badge-off!')
    if not badge:
        raise ValueError("badge does not exist")
    http_client = get_http_client()
    main()
